import {DescExtension, DescField, LongType, protoInt64, ScalarType, ScalarValue} from "@bufbuild/protobuf";

/**
 * Returns the zero value for the given scalar type.
 */
export function scalarZeroValue<T extends ScalarType, L extends LongType>(
    type: T,
    longType: L,
): ScalarValue<T, L> {
    switch (type) {
        case ScalarType.BOOL:
            return false as ScalarValue<T>;
        case ScalarType.UINT64:
        case ScalarType.FIXED64:
        case ScalarType.INT64:
        case ScalarType.SFIXED64:
        case ScalarType.SINT64:
            // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison -- acceptable since it's covered by tests
            return (longType == 0 ? protoInt64.zero : "0") as ScalarValue<T, L>;
        case ScalarType.DOUBLE:
        case ScalarType.FLOAT:
            return 0.0 as ScalarValue<T>;
        case ScalarType.BYTES:
            return new Uint8Array(0) as ScalarValue<T>;
        case ScalarType.STRING:
            return "" as ScalarValue<T>;
        default:
            // Handles INT32, UINT32, SINT32, FIXED32, SFIXED32.
            // We do not use individual cases to save a few bytes code size.
            return 0 as ScalarValue<T>;
    }
}

export function getUnwrappedFieldType(
    field: DescField | DescExtension,
): ScalarType | undefined {
    if (field.fieldKind !== "message") {
        return undefined;
    }
    if (field.repeated) {
        return undefined;
    }
    if (field.oneof != undefined) {
        return undefined;
    }
    return wktWrapperToScalarType[field.message.typeName];
}

const wktWrapperToScalarType: Record<string, ScalarType> = {
    "google.protobuf.DoubleValue": ScalarType.DOUBLE,
    "google.protobuf.FloatValue": ScalarType.FLOAT,
    "google.protobuf.Int64Value": ScalarType.INT64,
    "google.protobuf.UInt64Value": ScalarType.UINT64,
    "google.protobuf.Int32Value": ScalarType.INT32,
    "google.protobuf.UInt32Value": ScalarType.UINT32,
    "google.protobuf.BoolValue": ScalarType.BOOL,
    "google.protobuf.StringValue": ScalarType.STRING,
    "google.protobuf.BytesValue": ScalarType.BYTES,
};